package com.example.springbootdemoelasticsearch.service;

import com.example.springbootdemoelasticsearch.model.Person;
import com.example.springbootdemoelasticsearch.repository.PersonRepository;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
@Slf4j
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;
    @Autowired
    private PersonRepository repo;

    /**
     * 用户添加功能
     *
     * @param person
     * @return
     */
    @Override
    public Person save(Person person) {
        try {
            Person save = personRepository.save(person);
            log.info("用户添加" + save.toString());
            return save;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("在添加用户信息时报错");
            return null;
        }
    }

    /**
     * 批量添加
     *
     * @param personList
     * @return
     */
    @Override
    public Iterable<Person> saveAll(List<Person> personList) {
        try {
            Iterable<Person> people = personRepository.saveAll(personList);
            for (Person person : people) {
                log.info("用户添加:" + person.toString());
            }
            return people;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("批量添加用户信息时报错");
            return null;
        }
    }

    @Override
    public Boolean update(Person person1) {
        try {
             personRepository.findById(person1.getId()).ifPresent( person ->{
                     person.setRemark(person.getRemark() + "\n更新更新更新更新更新");
                     person.setName("王聪聪");
                     Person save = repo.save(person);
                     log.info("【save】= {}", save);
                    });
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
    public Boolean delete(long id){
        // 主键删除
        repo.deleteById(1L);

        // 对象删除
        repo.findById(2L).ifPresent(person -> repo.delete(person));

        // 批量删除
        repo.deleteAll(repo.findAll());
        return true;
    }

    @Override
    public void select() {
        repo.findAll( Sort.by(Sort.Direction.DESC, "birthday") )
                .forEach(person -> log.info("{} 生日: {}", person.getName()+person.getBirthday()));
    }

    @Override
    public List<Person> customAdvanceSelect(String name) {
        // 构造查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词条件
        queryBuilder.withQuery(QueryBuilders.matchQuery("remark", "东汉"));
        // 排序条件
        queryBuilder.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC));
        // 分页条件
        queryBuilder.withPageable(PageRequest.of(0, 2));
        Page<Person> people = repo.search(queryBuilder.build());
        log.info("【people】总条数 = {}", people.getTotalElements());
        log.info("【people】总页数 = {}", people.getTotalPages());
        people.forEach(person -> log.info("【person】= {}，年龄 = {}", person.getName(), person.getAge()));
        return null;
    }

    @Override
    public String agg() {
   //     构造查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
 //       不查询任何结果
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

 //       平均年龄
        queryBuilder.addAggregation(AggregationBuilders.avg("avg").field("age"));

        log.info("【queryBuilder】= {}", JSONUtil.toJsonStr(queryBuilder.build()));

        AggregatedPage<Person> people = (AggregatedPage<Person>) repo.search(queryBuilder.build());
        double avgAge = ((InternalAvg) people.getAggregation("avg")).getValue();
        log.info("【avgAge】= {}", avgAge);
        return null;
    }



}
